import threading, pp

class OrinMCore:

	def __init__(self, paswd='abcd'):
		# Pswd in local etc #
		self.pswd = paswd
		self.threadType = {'S':self.toThreading, 'M':self.MultiThreading}

	def CommQ(self, joblist, svrlist, funcName, ncpu, arg1, arg2=()):
		''' Distributing all jobs to all svrs at the same time. '''
		AnaJob = []
		tmplist = []
		#print joblist
		job_svr = pp.Server(ncpu, ppservers = svrlist, secret=self.pswd)
		for singlejob in joblist:
			tmplist.extend(arg1)
			tmplist.append(singlejob) 
			AnaJob.append((singlejob, job_svr.submit(funcName, tuple(tmplist), (), arg2)))
			del tmplist
			tmplist = []

		for Jobname, jobnow in AnaJob:
			JobNow = jobnow()
			if JobNow:
				print '%s is ok.' % Jobname
			del JobNow
		else:
			print job_svr.print_stats()
			return 'All is ok'
		return 'Somethings is wrong, check log pls.'

	def ThreadGo(self, ThreadFuncName, funcName, svrlist, ncpu, arg1, arg2, callback=''):
		''' ThreadFuncName: 'S', single job to Mulit svrs; 'M', Multi jobs to Multi svrs'''
		threads = []
		for svrtmp in svrlist:
			if callback:
				threads.append(threading.Thread(target=self.threadType[ThreadFuncName], args=(funcName, svrtmp, ncpu, arg1, arg2, callback)))
			else:
				#threads.append(threading.Thread(target=self.threadType[ThreadFuncName], args=(funcName, svrtmp, ncpu, tuple(arg1[-1]), tuple(arg1[:-1]), arg2)))
				threads.append(threading.Thread(target=self.threadType[ThreadFuncName], args=(funcName, svrtmp, ncpu, arg1, arg2)))

		for threads_1 in threads:
			threads_1.start()

		for threads_wait in threads:
			threads_wait.join()

		del threads, threads_1, threads_wait
		return 'All done.'


	def toThreading(self, funcName, svr, ncpu, arg1, arg2, callback=''):
		''' This Func is designed for distributing 1 job to multi Svrs at the same time'''
		#print ":",callback
		threadName = threading.currentThread().getName()
		svrlist = (svr,)
		if ncpu == '1':
			ppservers = ()
			job_server = pp.Server(ppservers=ppservers, secret=self.pswd)
		else:
			job_server = pp.Server(ncpu, ppservers=svrlist, secret=self.pswd)
		job_all = job_server.submit(funcName, arg1, (), arg2)
		m = job_all()
		if m:
			if callback:
				callback(m)
			#print '%s: %s is ok.' % (threadName, svrlist)
		else:
			print '%s if failed.' % threadName
		return 'ok'

	def MultiThreading(self, funcName, svr, ncpu, arg1, arg2, callback=''):
		'''List of jobs in Func Args must place at the end of the tuple. This func is designed for distributing lots of jobs to multi Svrs at the same time. '''
		threadName = threading.currentThread().getName()
		svrlist = (svr,)
		joblist = tuple(arg1[-1])
		arg1 = tuple(arg1[:-1])
		funcArg = []
		if ncpu == '1':
			ppservers = ()
			job_server = pp.Server(ppservers=ppservers, secret=self.pswd)
		else:
			job_server = pp.Server(ncpu, ppservers=svrlist, secret=self.pswd)
		AnaJob = []
		if not joblist: return False

		for onejob in joblist:
			funcArg.extend(arg1)
			funcArg.append(onejob)
			AnaJob.append((onejob, job_server.submit(funcName, tuple(funcArg), (), arg2)))
			del funcArg
			funcArg = []

		for jName, job_now in AnaJob:
			m = job_now()
			if m:
				if callback:
					callback(m)
				#print '%s: %s is ok.' % (svrlist, jName)
			else:
				print '%s if failed.' % threadName
		job_server.print_stats()
		return '%s is ok' % svr

	def ClearTMP(self, tmpdir, logstr):
		from oRinPackage import SafeRsync
		import os
		GetIP = SafeRsync.SafeRsync(0)
		for oldfile in filter(lambda x: logStr in x, os.listdir(tmpdir)): 
			os.remove('%s/%s' % (tmpdir, oldfile))
		return '%s is clear.' % GetIP.svrIP
